Skip to content

Make HttpQueryError hashable #8

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 19, 2018

Conversation

tlinhart
Copy link

As stated in the documentation for __hash__() method in Python 3, if class overrides __eq__() but doesn't define __hash__(), this will implicitely be set to None. This is the case of HttpQueryError exception class. This causes issues for logging, particularly traceback module which raises TypeError: unhashable type: 'HttpQueryError'.

Consider this minimal example:

import logging
from graphql_server import HttpQueryError

logger = logging.getLogger(__name__)

try:
    raise HttpQueryError(400, 'Error')
except HttpQueryError as e:
    logger.exception(e)

This results in:

--- Logging error ---
Traceback (most recent call last):
  File "/usr/lib/python3.5/logging/__init__.py", line 980, in emit
    msg = self.format(record)
  File "/usr/lib/python3.5/logging/__init__.py", line 830, in format
    return fmt.format(record)
  File "/usr/lib/python3.5/logging/__init__.py", line 575, in format
    record.exc_text = self.formatException(record.exc_info)
  File "/usr/lib/python3.5/logging/__init__.py", line 525, in formatException
    traceback.print_exception(ei[0], ei[1], tb, None, sio)
  File "/usr/lib/python3.5/traceback.py", line 100, in print_exception
    type(value), value, tb, limit=limit).format(chain=chain):
  File "/usr/lib/python3.5/traceback.py", line 439, in __init__
    _seen.add(exc_value)
TypeError: unhashable type: 'HttpQueryError'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "test_minimal.py", line 9, in <module>
    logger.exception(e)
  File "/usr/lib/python3.5/logging/__init__.py", line 1314, in exception
    self.error(msg, *args, exc_info=exc_info, **kwargs)
  File "/usr/lib/python3.5/logging/__init__.py", line 1308, in error
    self._log(ERROR, msg, args, **kwargs)
  File "/usr/lib/python3.5/logging/__init__.py", line 1415, in _log
    self.handle(record)
  File "/usr/lib/python3.5/logging/__init__.py", line 1425, in handle
    self.callHandlers(record)
  File "/usr/lib/python3.5/logging/__init__.py", line 1495, in callHandlers
    lastResort.handle(record)
  File "/usr/lib/python3.5/logging/__init__.py", line 855, in handle
    self.emit(record)
  File "/usr/lib/python3.5/logging/__init__.py", line 986, in emit
    self.handleError(record)
  File "/usr/lib/python3.5/logging/__init__.py", line 908, in handleError
    traceback.print_exception(t, v, tb, None, sys.stderr)

This PR adds __hash__() method for HttpQueryError class implemented as a call to hash() built-in function supplying tuple of components used in __eq__() (as suggested in the documentation).

Note: This issue should be solved in Python 3.6 and Python 3.7 (see Issue 28603) which fixes formatting of tracebacks for unhashable exceptions.

@syrusakbary syrusakbary merged commit a51bd66 into graphql-python:master Jul 19, 2018
@tlinhart tlinhart deleted the hashable-httpqueryerror branch July 20, 2018 05:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants